package com.linking.third.party.util;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Date;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author YaoWeiXin
 * @Date 2020/5/6 13:57
 * @Description JWT验证工具类
 */
@Slf4j
public class JwtUtils {

  public static DecodedJWT checkToken(String token) {
    return checkToken(token, null, null, null);
  }

  public static DecodedJWT checkToken(String token, String isUser) {
    return checkToken(token, isUser, null, null);
  }

  public static DecodedJWT checkToken(String token, String isUser, PublicKey publicKey) {
    return checkToken(token, isUser, publicKey, null);
  }

  public static DecodedJWT checkToken(String token, String isUser, PublicKey publicKey, PrivateKey privateKey) {
    DecodedJWT jwt;
    if (publicKey != null) {
      Algorithm algorithm;
      try {
        algorithm = Algorithm.RSA256((RSAPublicKey) publicKey, (RSAPrivateKey) privateKey);
      } catch (IllegalArgumentException e) {
        throw new RuntimeException(e);
      }
      JWTVerifier verifier = JWT.require(algorithm).build();
      jwt =  verifier.verify(token);
    } else {
      jwt = JWT.decode(token);
    }
    String rs256 = "RS256";
    if (!rs256.equals(jwt.getAlgorithm())) {
      log.debug("JwtUtils checkToken algorithm is not rs256");
      return null;
    }
    Date curDate = new Date();
    if (DateUtil.between(curDate, jwt.getExpiresAt(), DateUnit.SECOND, false) <= 0) {
      log.debug("JwtUtils checkToken expiresAt========{}", DateUtil.format(jwt.getExpiresAt(), "yyyyMMdd hh:mm:ss"));
      return null;
    }
    // 暂时不验证生成时间
//    if (DateUtil.between(jwt.getIssuedAt(), curDate, DateUnit.SECOND, false) <= 0) {
//      log.debug("JwtUtils checkToken issuedAt========{}", DateUtil.format(jwt.getIssuedAt(), "yyyyMMdd hh:mm:ss"));
//      return null;
//    }
    if (StrUtil.isNotEmpty(isUser) && !isUser.equals(jwt.getIssuer())) {
      log.debug("JwtUtils checkToken isUser========{},{}", isUser, jwt.getIssuer());
      return null;
    }
    return jwt;
  }
}
